//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V0.1.0
#include "app_button.h"


static TaskHandle_t WHT_Button_Task_Handle;           //任务句柄
static WHT_Button_Driver_t WHT_Button;                //按键操作结构体


//按键中断里恢复按键任务一次
static void WHT_Start_Button_Task(void)
{
    portYIELD_FROM_ISR(xTaskResumeFromISR(WHT_Button_Task_Handle));//恢复任务
}

//独立按键中断回调函数
static void WHT_Independent_Button_Down_Interrupt_Callback(void)
{
    //当有独立按键外部中断发生时会调用此函数进行任务处理
    WHT_Start_Button_Task();
}
//矩阵按键中断回调函数
static void WHT_Matrix_Button_Down_Interrupt_Callback(void)
{
    //当有矩阵按键外部中断发生时会调用此函数进行任务处理
    WHT_Start_Button_Task();
}
//ADC按键中断回调函数
static void WHT_ADC_Button_Down_Interrupt_Callback(void)
{
    //当有ADC按键外部中断发生时会调用此函数进行任务处理
    WHT_Start_Button_Task();
}


#if Independent_Button_EN//独立按键弹起处理程序
static void WHT_Independent_Button_Down_Up(WHT_Independent_Button_Number_enum number)
{
    #define WHT_Independent_Button_State  WHT_Button.WHT_Button_State->Independent_Button_State //内嵌局部宏定义

    if (WHT_Independent_Button_State[number].Down_Count >= Keep_Press_Min_Time/Button_Task_Scan_Rate)//一直按
    {
        if (WHT_Independent_Button_State[number].Down_Count >= Button_Error/Button_Task_Scan_Rate)   //按键故障
        {
            printf("Independent Button %d Error\r\n",number);
        }
        else
        {
            printf("Keep_Press\r\n");
        }
    }
    else if (WHT_Independent_Button_State[number].Down_Count >= Long_Press_Min_Time/Button_Task_Scan_Rate)//长按
    {
        printf("Long_Press\r\n");
    }
    else if (WHT_Independent_Button_State[number].Down_Count >= Short_Press_Min_Time/Button_Task_Scan_Rate)//短按
    {
        extern TaskHandle_t WHT_OLED_Task_Handle;//任务句柄
        if (number == Independent_Button0)
        {
            ////xTaskNotify(WHT_OLED_Task_Handle, 1, eSetValueWithOverwrite);//通知OLED任务
        }
        else if (number == Independent_Button1)
        {
            ////xTaskNotify(WHT_OLED_Task_Handle, 2, eSetValueWithOverwrite);//通知OLED任务
        }
        printf("Short_Press\r\n");
    }
    printf("Independent_Button %d Down time =%dms\r\n",number,WHT_Independent_Button_State[number].Down_Count * Button_Task_Scan_Rate);
    WHT_Independent_Button_State[number].Down_Count = 0;
    WHT_Independent_Button_State[number].state = Button_No_Down;
}
static void WHT_Independent_Button_Check_Scan(void)
{
    uint32_t number;
#if Independent_Button_EXTI_EN//独立按键使用外部中断
    
    if (*WHT_Button.WHT_Independent_Button_Exti_Flag != 0)//需要扫描独立按键
    {
        for (number = 0; number < Independent_Button_Count; number++)                             //循环获取按键里的状态
        {
            if (((*WHT_Button.WHT_Independent_Button_Exti_Flag >> number) & 0x01) != 0)           //表示是第i按键有按下
            {
                WHT_Button.WHT_Independent_Button_Scan((WHT_Independent_Button_Number_enum)number);    //只扫描按下的按键
                if (WHT_Button.WHT_Button_State->Independent_Button_State[number].state == Button_Down_Up)//有按键弹起
                {
                    WHT_Independent_Button_Down_Up((WHT_Independent_Button_Number_enum)number);   //处理按键
                    WHT_Button.WHT_Independent_Button_Exti_Enable((WHT_Independent_Button_Number_enum)number);//开启中断，内部会清零之前的标志
                }
            }
            else if ((*WHT_Button.WHT_Independent_Button_Exti_Flag >> number) == 0)               //剩下的没有按键按下
                break;
        }
    }
#else//独立按键使用传统扫描法
    static uint8_t Start_Independent_Button_Flag = 0; //独立按键扫描标志

    if (Start_Independent_Button_Flag != 0)//需要扫描独立按键
    {
        WHT_Button.WHT_Independent_Button_Scan(ALL_Independent_Button);//扫描所有独立按键
        Start_Independent_Button_Flag = 0;//先清零
        for (number = 0; number < Independent_Button_Count; number++)//循环获取按键里的状态
        {
            if (WHT_Button.WHT_Button_State->Independent_Button_State[number].state == Button_Yes_Down)//有按键按下
            {
                Start_Independent_Button_Flag = 1;
                continue;
            }
            else if (WHT_Button.WHT_Button_State->Independent_Button_State[number].state == Button_Down_Up)//有按键弹起
            {
                WHT_Independent_Button_Down_Up((WHT_Independent_Button_Number_enum)number);                //处理按键
            }
        }
    }
    else//扫描独立按键看是否有按下
    {
        if (WHT_Button.WHT_Get_Independent_Button_State() == Button_Yes_Down)
        {
            Start_Independent_Button_Flag = 1;//独立按键启动扫描
        }
    }
#endif 
}
#endif
#if Matrix_Button_EN//矩阵按键弹起处理程序
static void WHT_Matrix_Button_Down_Up(uint8_t row,uint8_t col)
{
    #define WHT_Matrix_Button_State  WHT_Button.WHT_Button_State->Matrix_Button_State[row][col] //内嵌局部宏定义

    if (WHT_Matrix_Button_State.Down_Count >= Keep_Press_Min_Time/Button_Task_Scan_Rate)//一直按
    {
        printf("Keep_Press\r\n");
    }
    else if (WHT_Matrix_Button_State.Down_Count >= Long_Press_Min_Time/Button_Task_Scan_Rate)//长按
    {
        printf("Long_Press\r\n");
    }
    else if (WHT_Matrix_Button_State.Down_Count >= Short_Press_Min_Time/Button_Task_Scan_Rate)//短按
    {
        printf("Short_Press\r\n");
    }
    printf("Matrix_Button %d Down time =%d\r\n",row*col,WHT_Matrix_Button_State.Down_Count * Button_Task_Scan_Rate);
    WHT_Matrix_Button_State.Down_Count = 0;
    WHT_Matrix_Button_State.state = Button_No_Down;
}
static void WHT_Matrix_Button_Check_Scan(void)
{
    uint32_t col;
#if Matrix_Button_EXTI_EN//矩阵按键使用外部中断
if (*WHT_Button.WHT_Matrix_Button_Col_Exti_Flag != 0)//需要扫描矩阵按键
    {
        uint8_t row;
        for (col = 0; col < Matrix_Button_Col; col++)
        {
            if (((*WHT_Button.WHT_Matrix_Button_Col_Exti_Flag >> col) & 0x01) != 0)                        //表示是第i列按键有按下
            {
                WHT_Button.WHT_Matrix_Button_Scan((WHT_Matrix_Button_Col_enum)col);                        //只扫描按下列的按键
                for (row = 0; row < Matrix_Button_Row; row++)
                {
                    if (WHT_Button.WHT_Button_State->Matrix_Button_State[row][col].state == Button_Down_Up)//有按键弹起
                    {
                        WHT_Matrix_Button_Down_Up(row, col);                                               //处理按键
                        WHT_Button.WHT_Matrix_Button_Exti_Enable((WHT_Matrix_Button_Col_enum)col);         //开启中断，内部会清零之前的标志
                    }
                }
            }
            else if ((*WHT_Button.WHT_Matrix_Button_Col_Exti_Flag >> col) == 0)                            //剩下的没有按键按下
                break;
        }
    }
#else//矩阵按键使用传统扫描法
    static uint8_t Start_Matrix_Button_Flag = 0;//矩阵按键扫描标志

    if (Start_Matrix_Button_Flag != 0)//需要扫描矩阵按键
    {
        uint8_t row;
        WHT_Button.WHT_Matrix_Button_Scan(ALL_Matrix_Button_Col);//扫描所有矩阵按键
        Start_Matrix_Button_Flag = 0;//先清零
        for (col = 0; col < Matrix_Button_Col; col++)//循环获取按键里的状态
        {
            for (row = 0; row < Matrix_Button_Row; row++)
            {
                if (WHT_Button.WHT_Button_State->Matrix_Button_State[row][col].state == Button_Yes_Down)//有按键按下
                {
                    Start_Matrix_Button_Flag = 1;
                    continue;
                }
                else if (WHT_Button.WHT_Button_State->Matrix_Button_State[row][col].state == Button_Down_Up)//有按键弹起
                {
                    WHT_Matrix_Button_Down_Up(row ,col);
                }
            }
        }
    }
    else//扫描独立按键看是否有按下
    {
        if (WHT_Button.WHT_Get_Matrix_Button_State() == Button_Yes_Down)
        {
            Start_Matrix_Button_Flag = 1;//矩阵按键启动扫描
        }
    }
#endif
}
#endif




static void WHT_Button_Task(void* pvParameters)
{
    for (; ;)
    {
        vTaskDelay(Button_Task_Scan_Rate/portTICK_RATE_MS);//按键扫描周期一般20毫秒

#if Independent_Button_EN
        WHT_Independent_Button_Check_Scan();//包含了传统扫描和中断扫描
#endif

#if Matrix_Button_EN
        WHT_Matrix_Button_Check_Scan();//包含了传统扫描和中断扫描
#endif

//此范例是独立和矩阵的中断均开启 
#if (Independent_Button_EXTI_EN & Matrix_Button_EXTI_EN)//独立 矩阵中断都使能
        if ((*WHT_Button.WHT_Independent_Button_Exti_Flag == 0) && (*WHT_Button.WHT_Matrix_Button_Col_Exti_Flag == 0))//表示已经没有按键按下了
        {
            vTaskSuspend(NULL);//此任务进行挂起
        }
#elif Independent_Button_EXTI_EN
        if (*WHT_Button.WHT_Independent_Button_Exti_Flag == 0)//这个范例是当前我的独立按键中断开启，矩阵不适用
        {
            vTaskSuspend(NULL);//此任务进行挂起
        }
#endif
    }
}


static void WHT_Button_Install(uint8_t task_priority)
{
    BaseType_t xreturn;

    WHT_Button_Driver_Register(&WHT_Button);
    if (WHT_Button.WHT_Independent_Button_Exti_Config != NULL)
        WHT_Button.WHT_Independent_Button_Exti_Config(WHT_Independent_Button_Down_Interrupt_Callback);
    if (WHT_Button.WHT_Matrix_Button_Exti_Config != NULL)
        WHT_Button.WHT_Matrix_Button_Exti_Config(WHT_Matrix_Button_Down_Interrupt_Callback);

    xreturn = xTaskCreate( WHT_Button_Task, "WHT_Button_Task", 256, NULL, task_priority, &WHT_Button_Task_Handle);
    if (xreturn == pdPASS)
        printf("WHT:Button Task Create OK!\r\n");
    else
        printf("WHT:Button Task Create Error!\r\n");
}

static void WHT_Button_Uninstall(void)
{
    vTaskDelete(WHT_Button_Task_Handle);
    printf("WHT:Button Task Delete OK!\r\n");
}


void WHT_Button_Init(uint8_t task_priority, WHT_Button_t* button)
{
    button->Button_Task_Install   = WHT_Button_Install;
    button->Button_Task_Uninstall = WHT_Button_Uninstall;
    WHT_Button_Install(task_priority);
}
